/*
 *      Author: Guannan Ma
 *      @mythmgn
 *      Whatever license applied
 */

#include "base.h"

#ifndef BASE_LIB_LIBDLT_H
#define BASE_LIB_LIBDLT_H

typedef struct dLinkNode{
	struct dLinkNode *next;
	struct dLinkNode *previous;
	char *key;
	void *data;
}dLinkNode;

typedef dLinkNode dLinkPos;

/*Can only access member key and data*/
typedef dLinkNode dLinkNodeInfo;

typedef struct dLinkList{

    /**< If the head is NULL, the list is empty
     * The head node will store key and data as well.
     * The tail node will NOT store key and data.
     * */

	dLinkNode *head;

	/**< The tail node
        temp_tail->key=NULL;
	    temp_tail->data=NULL;
		temp_tail->next=p_dll->head;
    */
	dLinkNode *tail;

	int length;
}dLinkList;

dLinkList *initDLinkList();

/* When p_dll->head=NULL, the DLT is empty.
 * */
BOOL isDLinkListEmpty(dLinkList *p_dll);

EXBOOL isTailOfDlinkList(dLinkList *p_dll,dLinkNodeInfo *dinfo);

dLinkNodeInfo* traverseCycleDLinkList(dLinkList *p_dll,dLinkPos **pos);

BOOL addDLinkListItem(dLinkList *p_dll,char *key,void *p_data);

BOOL delDLinkListWithKey(dLinkList *p_dll,char *key);

BOOL delDLinkListWithNodeInfo(dLinkList *p_dll,dLinkNodeInfo *pos);

BOOL emptyDLinkListItem(dLinkList *p_dll);

BOOL freeDLinkList(dLinkList *p_dll,BOOL freeContent);

void *getDataDLinkList(dLinkList *p_dll,char *key);

/*  return the length of the dlinklist. If p_dll==NULL, return -1
 * */
int getDLinkListLength(dLinkList *p_dll);


/*
 * The function will return a dLinkNodeInfo until *pos reaches the tail of the linklist.
 * a dLinkNodeInfo can be used like below.
 *
 * 	dLinkNodeInfo *p;
 *  void *a=p->data;
 *  char *b=p->key;
 *
 *
 * */
dLinkNodeInfo* traverseDLinkListUntilTail(dLinkList *p_dll,dLinkPos **pos);

#endif // LIB_DLT_H_INCLUDED
